# This is a BitKeeper generated patch for the following project: # Project Name: Linux kernel tree # This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas: # ChangeSet 1.676.12.10 -> 1.676.12.11 # include/asm-ia64/pal.h 1.4 -> 1.5 # include/asm-ia64/sal.h 1.7 -> 1.8 # arch/ia64/kernel/ia64_ksyms.c 1.6 -> 1.7 # arch/ia64/kernel/pal.S 1.4 -> 1.5 # # The following is the BitKeeper ChangeSet Log # -------------------------------------------- # 02/09/27 jsm@udlkern.fc.hp.com 1.676.12.11 # ia64: Preserve f11-f15 around calls into firmware. # -------------------------------------------- # diff -Nru a/arch/ia64/kernel/ia64_ksyms.c b/arch/ia64/kernel/ia64_ksyms.c --- a/arch/ia64/kernel/ia64_ksyms.c Wed Oct 8 09:09:26 2003 +++ b/arch/ia64/kernel/ia64_ksyms.c Wed Oct 8 09:09:26 2003 @@ -141,6 +141,8 @@ EXPORT_SYMBOL(ia64_pal_call_phys_static); EXPORT_SYMBOL(ia64_pal_call_stacked); EXPORT_SYMBOL(ia64_pal_call_static); +EXPORT_SYMBOL(ia64_load_scratch_fpregs); +EXPORT_SYMBOL(ia64_save_scratch_fpregs); extern struct efi efi; EXPORT_SYMBOL(efi); diff -Nru a/arch/ia64/kernel/pal.S b/arch/ia64/kernel/pal.S --- a/arch/ia64/kernel/pal.S Wed Oct 8 09:09:26 2003 +++ b/arch/ia64/kernel/pal.S Wed Oct 8 09:09:26 2003 @@ -245,3 +245,49 @@ br.ret.sptk.many b0 END(ia64_pal_call_phys_stacked) +/* + * Save scratch fp scratch regs (fp10-fp15) + * + * NOTE: We need to do this since firmware (SAL or PAL) uses more + * scratch fp regs than the Linux kernel does. + * + * Inputs: + * in0 Address of stack storage for fp regs + */ + +GLOBAL_ENTRY(ia64_save_scratch_fpregs) + alloc r3=ar.pfs,1,0,0,0 + add r2=16,in0 + ;; + stf.spill [in0] = f10,32 + stf.spill [r2] = f11,32 + ;; + stf.spill [in0] = f12,32 + stf.spill [r2] = f13,32 + ;; + stf.spill [in0] = f14,32 + stf.spill [r2] = f15,32 + br.ret.sptk.many rp +END(ia64_save_scratch_fpregs) + +/* + * Load scratch fp scratch regs (fp10-fp15) + * + * Inputs: + * in0 Address of stack storage for fp regs + */ + +GLOBAL_ENTRY(ia64_load_scratch_fpregs) + alloc r3=ar.pfs,1,0,0,0 + add r2=16,in0 + ;; + ldf.fill f10 = [in0],32 + ldf.fill f11 = [r2],32 + ;; + ldf.fill f12 = [in0],32 + ldf.fill f13 = [r2],32 + ;; + ldf.fill f14 = [in0],32 + ldf.fill f15 = [r2],32 + br.ret.sptk.many rp +END(ia64_load_scratch_fpregs) diff -Nru a/include/asm-ia64/pal.h b/include/asm-ia64/pal.h --- a/include/asm-ia64/pal.h Wed Oct 8 09:09:26 2003 +++ b/include/asm-ia64/pal.h Wed Oct 8 09:09:26 2003 @@ -78,6 +78,7 @@ #ifndef __ASSEMBLY__ #include +#include /* * Data types needed to pass information into PAL procedures and @@ -650,11 +651,43 @@ extern struct ia64_pal_retval ia64_pal_call_phys_static (u64, u64, u64, u64); extern struct ia64_pal_retval ia64_pal_call_phys_stacked (u64, u64, u64, u64); -#define PAL_CALL(iprv,a0,a1,a2,a3) iprv = ia64_pal_call_static(a0, a1, a2, a3, 0) -#define PAL_CALL_IC_OFF(iprv,a0,a1,a2,a3) iprv = ia64_pal_call_static(a0, a1, a2, a3, 1) -#define PAL_CALL_STK(iprv,a0,a1,a2,a3) iprv = ia64_pal_call_stacked(a0, a1, a2, a3) -#define PAL_CALL_PHYS(iprv,a0,a1,a2,a3) iprv = ia64_pal_call_phys_static(a0, a1, a2, a3) -#define PAL_CALL_PHYS_STK(iprv,a0,a1,a2,a3) iprv = ia64_pal_call_phys_stacked(a0, a1, a2, a3) +extern void ia64_save_scratch_fpregs(struct ia64_fpreg *); +extern void ia64_load_scratch_fpregs(struct ia64_fpreg *); + +#define PAL_CALL(iprv,a0,a1,a2,a3) do { \ + struct ia64_fpreg fr[6]; \ + ia64_save_scratch_fpregs(fr); \ + iprv = ia64_pal_call_static(a0, a1, a2, a3, 0); \ + ia64_load_scratch_fpregs(fr); \ +} while (0) + +#define PAL_CALL_IC_OFF(iprv,a0,a1,a2,a3) do { \ + struct ia64_fpreg fr[6]; \ + ia64_save_scratch_fpregs(fr); \ + iprv = ia64_pal_call_static(a0, a1, a2, a3, 1); \ + ia64_load_scratch_fpregs(fr); \ +} while (0) + +#define PAL_CALL_STK(iprv,a0,a1,a2,a3) do { \ + struct ia64_fpreg fr[6]; \ + ia64_save_scratch_fpregs(fr); \ + iprv = ia64_pal_call_stacked(a0, a1, a2, a3); \ + ia64_load_scratch_fpregs(fr); \ +} while (0) + +#define PAL_CALL_PHYS(iprv,a0,a1,a2,a3) do { \ + struct ia64_fpreg fr[6]; \ + ia64_save_scratch_fpregs(fr); \ + iprv = ia64_pal_call_phys_static(a0, a1, a2, a3);\ + ia64_load_scratch_fpregs(fr); \ +} while (0) + +#define PAL_CALL_PHYS_STK(iprv,a0,a1,a2,a3) do { \ + struct ia64_fpreg fr[6]; \ + ia64_save_scratch_fpregs(fr); \ + iprv = ia64_pal_call_phys_stacked(a0, a1, a2, a3); \ + ia64_load_scratch_fpregs(fr); \ +} while (0) typedef int (*ia64_pal_handler) (u64, ...); extern ia64_pal_handler ia64_pal; diff -Nru a/include/asm-ia64/sal.h b/include/asm-ia64/sal.h --- a/include/asm-ia64/sal.h Wed Oct 8 09:09:26 2003 +++ b/include/asm-ia64/sal.h Wed Oct 8 09:09:26 2003 @@ -38,9 +38,12 @@ # define SAL_CALL(result,args...) do { \ unsigned long flags; \ + struct ia64_fpreg fr[6]; \ + ia64_save_scratch_fpregs(fr); \ spin_lock_irqsave(&sal_lock, flags); \ __SAL_CALL(result,args); \ spin_unlock_irqrestore(&sal_lock, flags); \ + ia64_load_scratch_fpregs(fr); \ } while (0) #define SAL_SET_VECTORS 0x01000000